# -*- coding: utf-8 -*-
# @Time    : 2020/7/15 10:20
# @Author  : ZhaoHexin
# @File    : RunUi.py
# @Description  : UI展现
import time

from PyQt5.QtCore import Qt, QThread, pyqtSignal
from PyQt5.QtWidgets import QDialog, QApplication, QFileDialog, QMessageBox, QCompleter
from PyQt5 import QtWidgets, QtCore

import sys
import os
import shutil
import configparser

from configobj import ConfigObj

from SsoCreateUi import UiSsoCreate
from config import InfoConfig
from CreateSsoFile.CreateSso import CreateSso
from CreateSsoFile.DecodeSso import DecodeSso
from CreateSsoFile.EncodeSso import EncodeSso
from CreateSsoFile.BatchEncodeSso import BatchEncodeSso


class Worker(QThread):
    progressBarValue = pyqtSignal(int)  # 更新进度条

    def __init__(self):
        super(Worker, self).__init__()

    def run(self):
        BatchEncodeSso(self.progressBarValue, form).create_sso()


class PaymentDlg(QDialog, UiSsoCreate):
    """
    Class documentation goes here.
    """

    def __init__(self, parent=None):
        """
        Constructor

        @param parent reference to the parent widget
        @type QWidget
        """
        super(PaymentDlg, self).__init__(parent)
        self.setupUi(self)
        self.create_history()
        self.history_data = configparser.ConfigParser()
        self.history_data.read(InfoConfig.temp_path, encoding="utf-8")
        # 进行历史数据读取
        self.user_history = self.get_history_data_user()
        self.pwd_history = self.get_history_data_pwd()
        self.major_code_history = self.get_history_data_majorcode()
        self.major_name_history = self.get_history_data_majorname()
        self.regioncode_history = self.get_history_data_regioncode()
        self.encrypt_decrypt_histoyr = self.get_history_data_encrypt_decrypt()
        self.batch_history = self.get_history_data_batch()
        # 初始化自动补全
        self.init_user()
        self.init_pwd()
        self.init_batch()
        self.init_majorcode()
        self.init_encrypt_decrypt()
        self.init_majorname()
        self.init_regioncode()

    def tabchange(self):
        """
        切换页签触发操作
        :return:
        """
        print("index:", self.tabWidget.currentIndex())
        # 更新页签Id
        InfoConfig.currentIndex = self.tabWidget.currentIndex()
        # 判断当前ID，进行锁对应按钮功能
        if InfoConfig.currentIndex == 1 and self.pathEdit.text() != "":
            self.pushButton_decode.setEnabled(True)
            self.pushButton_encryption.setEnabled(True)
        elif InfoConfig.currentIndex == 0:
            self.pushButton_decode.setEnabled(False)
            self.pushButton_encryption.setEnabled(True)
        elif InfoConfig.currentIndex == 2 and self.declassifiedsPathEdit.text() != "":
            self.pushButton_decode.setEnabled(False)
            self.pushButton_encryption.setEnabled(True)
        else:
            self.pushButton_decode.setEnabled(False)
            self.pushButton_encryption.setEnabled(False)

    def check_dir(self):
        """
        实现选择文件夹后向相应的LineEdit赋值
        :param LineEdit:
        :return:
        """
        dir = QFileDialog.getExistingDirectory()
        self.pathLineEdit.setText(dir)

    def click_encryption(self):
        """
        点击加密按钮后触发操作
        :return:
        """
        # 获取页面内容并存储到参数文件中
        self.get_ui_data()
        # 判断必填项是否都填了
        # 判断页签功能
        if InfoConfig.currentIndex != 1:
            if InfoConfig.usernames:
                if InfoConfig.passwords:
                    if InfoConfig.majorcodes:
                        if len(InfoConfig.majorcodes) == len(list(dict.fromkeys(InfoConfig.majorcodes))):
                            if InfoConfig.regioncodes or InfoConfig.currentIndex == 2:
                                # 根据页签，展开不同的功能
                                if InfoConfig.currentIndex == 0:
                                    self.encryption_one()
                                    # 进行历史数据保存
                                    self.save_history()
                                elif InfoConfig.currentIndex == 2:
                                    if InfoConfig.is_click:
                                        self.encryption_three()
                                        # 进行历史数据保存
                                        self.save_history()
                                    else:
                                        self.warning_popup_windows("已经有一个在跑咯，不怕死机么")
                            else:
                                self.warning_popup_windows("注册码一定要输入哦！")
                        else:
                            self.warning_popup_windows("专业标识不能重复哦！")
                    else:
                        self.warning_popup_windows("专业标识一定要输入哦！")
                else:
                    self.warning_popup_windows("密码一定要输入哦！")
            else:
                self.warning_popup_windows("用户名一定要输入哦！")
        else:
            self.encryption_two()
            # 进行历史数据保存
            self.save_history()

    def clikc_decode(self):
        """
        点击解密按钮后操作
        :return:
        """
        # 读取页面信息
        self.get_ui_data()
        # 进行历史数据留存
        self.save_history()
        # 判断文件是否存在
        if os.path.exists(InfoConfig.encryption_path):
            try:
                decode_info = DecodeSso().decode()
                # 进行解密输出
                self.textBrowser_1.append("")
                self.textBrowser_1.append("恭喜，解密成功了哦！以下是sso相关信息，请查看-")
                self.textBrowser_1.append("")
                self.textBrowser_1.append(f"文件路径为：{decode_info.get('path')}")
                self.textBrowser_1.append("")
                for info in decode_info.get("decode_info"):
                    self.textBrowser_1.append("*****************************************")
                    self.textBrowser_1.append(f"用户名：{info.get('username')}")
                    self.textBrowser_1.append(f"密码：{info.get('password')}")
                    self.textBrowser_1.append(f"专业标识：{info.get('majorcode')}")
                    self.textBrowser_1.append(f"专业中文名：{info.get('majorname')}")
                    self.textBrowser_1.append(f"注册码：{info.get('regioncode')}")
            except Exception as e:
                self.textBrowser_1.append("*****************************************")
                self.textBrowser_1.append(f"解密失败，请查看源文件是否正确：{e}")
        else:
            self.warning_popup_windows("找不到文件哦，请重新确认路径！")

    def warning_popup_windows(self, info):
        """
        警告弹窗
        :param info: 提示信息
        :return:
        """
        QMessageBox.warning(self, "警告", self.tr(info))

    def get_ui_data(self):
        """
        获取页面所有数据并存储到参数文件中
        :return:
        """
        usernames = list(filter(None, self.surnameLineEdit.text().replace("；", ";").split(";")))
        passwords = list(filter(None, self.forenameLineEdit.text().replace("；", ";").split(";")))
        majorcodes = list(filter(None, self.identityLineEdit.text().replace("；", ";").split(";")))
        majornames = list(filter(None, self.majorLineEdit.text().replace("；", ";").split(";")))
        regioncodes = list(filter(None, self.registrationCodeEdit.text().replace("；", ";").split(";")))
        path = self.pathLineEdit.text() if self.pathLineEdit.text() != "" else os.path.abspath(".")
        encryption_path = self.pathEdit.text()
        is_check = bool(self.paidCheckBox.checkState())
        batch_encryption_path = self.declassifiedsPathEdit.text()
        # 添加环境元素
        InfoConfig.usernames = usernames
        InfoConfig.passwords = passwords
        InfoConfig.majorcodes = majorcodes
        InfoConfig.majornames = majornames
        InfoConfig.regioncodes = regioncodes
        InfoConfig.path = path
        InfoConfig.encryption_path = encryption_path
        InfoConfig.is_check = is_check
        InfoConfig.batch_encryption_path = batch_encryption_path

    def encryption_one(self):
        """
        页签1加密功能
        :return:
        """
        # 创建sso文件并接收返回信息
        create_info = CreateSso(InfoConfig.usernames, InfoConfig.passwords, InfoConfig.majorcodes,
                                InfoConfig.majornames, InfoConfig.regioncodes, InfoConfig.path).create()

        # 将返回信息进行前端展示
        self.textBrowser.append("")
        self.textBrowser.append("恭喜，创建文件成功了哦！以下是sso相关信息，请查看-")
        self.textBrowser.append("")
        self.textBrowser.append(f"文件路径为：{create_info[0].get('path')}")
        self.textBrowser.append("")
        for info in create_info:
            self.textBrowser.append("*****************************************")
            self.textBrowser.append("")
            self.textBrowser.append("")
            self.textBrowser.append(f"用户名：{info.get('username')}")
            self.textBrowser.append(f"密码：{info.get('password')}")
            self.textBrowser.append(f"专业标识：{info.get('majorcode')}")
            self.textBrowser.append(f"专业中文名：{info.get('majorname')}")
            self.textBrowser.append(f"注册码：{info.get('regioncode')}")
            self.textBrowser.append("")
            self.textBrowser.append("")

    def encryption_two(self):
        """
        页签二加密功能
        :return:
        """
        # 加密文件
        path_ = EncodeSso().encode()
        self.textBrowser_1.append("")
        self.textBrowser_1.append("恭喜，文件加密成功了哦！以下是sso相关信息，请查看-")
        self.textBrowser_1.append("")
        self.textBrowser_1.append(f"文件路径为：{path_}")
        self.textBrowser_1.append("")

    def encryption_three(self):
        """
        页签三加密功能
        :return:
        """
        # 上锁
        InfoConfig.is_click = False
        self.thread_1 = Worker()
        self.thread_1.progressBarValue.connect(self.copy_file)
        self.thread_1.start()


    def copy_file(self, i):
        self.progressBar.setValue(i)

    def create_history(self):
        """
        创建临时文件，若不存在时
        :return:
        """
        # 获取临时文件目录
        history_path = InfoConfig.temp_path
        # 判断是否存在，不存则创建，并加入预置值
        if not os.path.exists(history_path):
            # 创建目录
            try:
                os.makedirs(os.path.dirname(history_path))
            except:
                pass
            # 写入预置数据
            user_history = ["thtf", "user"]
            pwd_history = ["12345678", "a"]
            major_code_history = ["2019ydldldc_00GJ"]
            major_name_history = ["劳动力月度调查"]
            regioncode_history = []
            encrypt_decrypt_history = []
            batch_history = []
            history = ConfigObj(history_path, encoding="utf-8")
            # 写入文件
            history["USER_HISTORY"] = {}
            history["PWD_HISTORY"] = {}
            history["MAJOR_CODE_HISTORY"] = {}
            history["MAJOR_NAME_HISTORY"] = {}
            history["REGIONCODE_HISTORY"] = {}
            history["ENCRYPT_DECRYPT_HISTORY"] = {}
            history["BATCH_HISTORY"] = {}
            history["USER_HISTORY"]["user_history"] = user_history
            history["PWD_HISTORY"]["pwd_history"] = pwd_history
            history["MAJOR_CODE_HISTORY"]["major_code_history"] = major_code_history
            history["MAJOR_NAME_HISTORY"]["major_name_history"] = major_name_history
            history["REGIONCODE_HISTORY"]["regioncode_history"] = regioncode_history
            history["ENCRYPT_DECRYPT_HISTORY"]["encrypt_decrypt_history"] = encrypt_decrypt_history
            history["BATCH_HISTORY"]["batch_history"] = batch_history
            history.write()

    def get_history_data_user(self):
        """
        进行历史数据读取-用户名
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("USER_HISTORY", "user_history").split(
                                 ","))) if self.history_data.get(
                    "USER_HISTORY",
                    "user_history") != '""' else []
                 )]

    def get_history_data_pwd(self):
        """
        进行历史数据读取-密码
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("PWD_HISTORY", "pwd_history").split(","))) if self.history_data.get(
                    "PWD_HISTORY",
                    "pwd_history") != '""' else []
                 )]

    def get_history_data_majorcode(self):
        """
        进行历史数据读取-专业标识
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("MAJOR_CODE_HISTORY", "major_code_history").split(
                                 ","))) if self.history_data.get(
                    "MAJOR_CODE_HISTORY",
                    "major_code_history") != '""' else []
                 )]

    def get_history_data_majorname(self):
        """
        进行历史数据读取-专业中文名称
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("MAJOR_NAME_HISTORY", "major_name_history").split(
                                 ","))) if self.history_data.get(
                    "MAJOR_NAME_HISTORY",
                    "major_name_history") != '""' else []
                 )]

    def get_history_data_regioncode(self):
        """
        进行历史数据读取-注册码
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("REGIONCODE_HISTORY", "regioncode_history").split(
                                 ","))) if self.history_data.get(
                    "REGIONCODE_HISTORY",
                    "regioncode_history") != '""' else []
                 )]

    def get_history_data_encrypt_decrypt(self):
        """
        进行历史数据读取-加密解密路径
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("ENCRYPT_DECRYPT_HISTORY", "encrypt_decrypt_history").split(
                                 ","))) if self.history_data.get(
                    "ENCRYPT_DECRYPT_HISTORY",
                    "encrypt_decrypt_history") != '""' else []
                 )]

    def get_history_data_batch(self):
        """
        进行历史数据读取-批量加密文件路径
        :return:
        """

        return [i.strip() for i in
                (list(filter(None,
                             self.history_data.get("BATCH_HISTORY", "batch_history").split(
                                 ","))) if self.history_data.get(
                    "BATCH_HISTORY",
                    "batch_history") != '""' else []
                 )]

    def init_user(self):
        """
        用户名自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.user_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.surnameLineEdit.setCompleter(self.completer)

    def init_pwd(self):
        """
        密码自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.pwd_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.forenameLineEdit.setCompleter(self.completer)

    def init_majorcode(self):
        """
        专业标识自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.major_code_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.identityLineEdit.setCompleter(self.completer)

    def init_majorname(self):
        """
        专业中文名称自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.major_name_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.majorLineEdit.setCompleter(self.completer)

    def init_regioncode(self):
        """
        注册码自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.regioncode_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.registrationCodeEdit.setCompleter(self.completer)

    def init_encrypt_decrypt(self):
        """
        加密/解密自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.encrypt_decrypt_histoyr)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.pathEdit.setCompleter(self.completer)

    def init_batch(self):
        """
        批量加密文件路径自动补全
        :return:
        """

        # 增加自动补全
        self.completer = QCompleter(self.batch_history)
        # 设置匹配模式 有三种： Qt.MatchStartsWith 开头匹配（默认） Qt.MatchContains 内容匹配 Qt.MatchEndsWith 结尾匹配
        self.completer.setFilterMode(Qt.MatchContains)
        # 设置补全模式 有三种： QCompleter.PopupCompletion（默认） QCompleter.InlineCompletion  QCompleter.UnfilteredPopupCompletion
        self.completer.setCompletionMode(QCompleter.PopupCompletion)
        # 给lineedit设置补全器
        self.declassifiedsPathEdit.setCompleter(self.completer)

    def save_history(self):
        """
        历史数据留存
        :return:
        """

        self.user_history.append(
            self.surnameLineEdit.text()) if \
            self.surnameLineEdit.text() not in self.user_history and \
            self.surnameLineEdit.text() != "" else self.user_history
        self.pwd_history.append(
            self.forenameLineEdit.text()) if \
            self.forenameLineEdit.text() not in self.pwd_history and \
            self.forenameLineEdit.text() != "" else self.pwd_history
        self.major_code_history.append(
            self.identityLineEdit.text()) if \
            self.identityLineEdit.text() not in self.major_code_history and \
            self.identityLineEdit.text() != "" else self.major_code_history
        self.major_name_history.append(
            self.majorLineEdit.text()) if \
            self.majorLineEdit.text() not in self.major_name_history and \
            self.majorLineEdit.text() != "" else self.major_name_history
        self.regioncode_history.append(
            self.registrationCodeEdit.text()) if \
            self.registrationCodeEdit.text() not in self.regioncode_history and \
            self.registrationCodeEdit.text() != "" else self.regioncode_history
        self.encrypt_decrypt_histoyr.append(
            self.pathEdit.text()) if \
            self.pathEdit.text() not in self.encrypt_decrypt_histoyr and \
            self.pathEdit.text() != "" else self.encrypt_decrypt_histoyr
        self.batch_history.append(
            self.declassifiedsPathEdit.text()) if \
            self.declassifiedsPathEdit.text() not in self.batch_history and \
            self.declassifiedsPathEdit.text() != "" else self.batch_history
        # 修改配置文件信息
        config = ConfigObj(InfoConfig.temp_path, encoding='UTF8')
        config['USER_HISTORY']['user_history'] = self.user_history
        config['PWD_HISTORY']['pwd_history'] = self.pwd_history
        config['MAJOR_CODE_HISTORY']['major_code_history'] = self.major_code_history
        config['MAJOR_NAME_HISTORY']['major_name_history'] = self.major_name_history
        config['REGIONCODE_HISTORY']['regioncode_history'] = self.regioncode_history
        config['ENCRYPT_DECRYPT_HISTORY']['encrypt_decrypt_history'] = self.encrypt_decrypt_histoyr
        config['BATCH_HISTORY']['batch_history'] = self.batch_history
        config.write()
        # 重置补全
        self.init_user()
        self.init_pwd()
        self.init_batch()
        self.init_majorcode()
        self.init_encrypt_decrypt()
        self.init_majorname()
        self.init_regioncode()

    def reset_history(self, event):
        """
        重置历史输入按钮
        :return:
        """
        reply = QMessageBox.warning(self, '警告', '将要清除所有输入框的历史纪录,\n确定要清除么？',
                                    QMessageBox.Yes, QMessageBox.No)
        if reply == QMessageBox.Yes:
            shutil.rmtree(os.path.dirname(InfoConfig.temp_path))
            self.create_history()
            # 重新初始化自动补全控件
            self.user_history = self.get_history_data_user()
            self.pwd_history = self.get_history_data_pwd()
            self.major_code_history = self.get_history_data_majorcode()
            self.major_name_history = self.get_history_data_majorname()
            self.regioncode_history = self.get_history_data_regioncode()
            self.encrypt_decrypt_histoyr = self.get_history_data_encrypt_decrypt()
            self.batch_history = self.get_history_data_batch()
            # 初始化自动补全
            self.init_user()
            self.init_pwd()
            self.init_batch()
            self.init_majorcode()
            self.init_encrypt_decrypt()
            self.init_majorname()
            self.init_regioncode()
            # 弹出提示窗口
            QMessageBox.information(self, "提示", f"重置完成。",
                                    QMessageBox.Yes)
        else:
            pass


if __name__ == "__main__":
    app = QApplication(sys.argv)
    form = PaymentDlg()
    form.show()

    form.tabWidget.currentChanged.connect(form.tabchange)
    form.pathEdit.textChanged.connect(form.tabchange)
    form.declassifiedsPathEdit.textChanged.connect(form.tabchange)
    form.pushButton.clicked.connect(form.check_dir)
    form.pushButton_encryption.clicked.connect(form.click_encryption)
    form.pushButton_decode.clicked.connect(form.clikc_decode)
    form.resetButton.clicked.connect(form.reset_history)
    app.exec_()
